<template>
  <div class="machineParameter">
    <DFPageList ref="dfPageListRef" :pageOptions="pageOptions">
      <template #interfaceJson>
        <json-editor-vue
          class="editor"
          v-model="interfaceJson"
          currentMode="code"
          :onChange="handleJsonChange(interfaceJson)"
        />
      </template>
    </DFPageList>
  </div>
</template>

<script lang="ts" setup name="GatherMachine">
  import lang from './lang';
  import { useMixins } from '@/hooks/useMixins';
  import {
    pageMachineParameter,
    delMachineParameter,
    addMachineParameter,
  } from '@/api/gather/machine';
  import { listMachine } from '@/api/base/machine';
  import JsonEditorVue from 'json-editor-vue3';
  import { listGatherParameter } from '@render/api/gather/parameter';
  import { v4 as uuidv4 } from 'uuid';

  const { loadLangFn, t } = useMixins();
  loadLangFn(lang);

  const dfPageListRef: any = ref(null);

  const machineList = ref([]);

  const gatherParameterList = ref([]);

  const interfaceJson = ref();

  const handleJsonChange = (e) => {
    dfPageListRef.value.setFieldsValueFn({ interfaceJson: e });

    if (e && Object.keys(e).length !== 0) {
      dfPageListRef.value?.validate(['interfaceJson']);
    }
  };

  const pageOptions = {
    searchForm: {
      formSchemas: [
        {
          component: 'NInput',
          label: 'accessName',
        },
        {
          component: 'NInput',
          label: 'accessCode',
        },
        {
          label: 'machineName',
          prop: 'machineCode',
          component: 'NSelect',
          options: machineList,
        },
      ],
    },
    table: {
      columns: [
        {
          width: 170,
          label: 'accessName',
        },
        {
          width: 170,
          label: 'accessCode',
        },
        {
          width: 170,
          label: 'machineName',
          render: (row) => {
            return h('span', {
              innerText: row.machineCode
                ? machineList.value.find((item) => item.value === row.machineCode).label
                : '-',
            });
          },
        },
        {
          width: 170,
          label: 'machineCode',
        },
        {
          width: 170,
          label: 'remark',
          common: true,
        },
      ],
      action: {
        columns: [
          {
            label: 'edit',
            hump: true,
          },
          {
            label: 'copy',
            hump: true,
          },
          {
            label: 'delete',
          },
        ],
      },
      operaColumn: [
        {
          label: 'add',
          hump: true,
        },
        {
          label: 'import',
          click: () => {
            if (dfPageListRef && dfPageListRef.value && dfPageListRef.value.openModalFn) {
              interfaceJson.value = {};

              dfPageListRef.value.openModalFn('import');
            }
          },
        },
      ],
      requestFn: pageMachineParameter,
      delRequestFn: delMachineParameter,
    },
    modalFormDialog: {
      formSchemas: [
        {
          label: 'accessName',
          required: true,
        },
        {
          label: 'accessCode',
          required: true,
        },
        {
          label: 'machineName',
          prop: 'machineCode',
          component: 'NSelect',
          options: machineList,
          required: true,
        },
        {
          label: 'interfaceJson',
          slot: 'interfaceJson',
          maxlength: '999999999',
          required: false,
          giProps: { span: 4 },
          span: 3,
          rules: [
            {
              required: true,
              key: 'interfaceJson',
              validator(_rule, value: string) {
                if (!value || Object.keys(value).length === 0) {
                  return new Error(t('common.formTipMsg.input'));
                }
              },
              trigger: ['blur', 'change'],
            },
          ],
        },
      ],
      setDialogSubmitDataFn: (data) => {
        const { accessCode, accessName, machineCode, interfaceJson } = data;

        const {
          connectType,
          host,
          ip = null,
          addressList: aAddressList = [],
          pAddressList = [],
          port = null,
          protocol = null,
          isOpenMultiLine,
        } = interfaceJson;

        const addressList = [...aAddressList, ...pAddressList];

        const iObj = {
          accessCode,
          accessName,
          machineCode,
          ...interfaceJson,
          connectionType: connectType === 'modbus' ? protocol : protocol,
          protocol: connectType === 'modbus' ? null : protocol,
          ip: ip || connectType === 'opcua' ? ip : host,
          port: port || connectType === 'fins' ? 9600 : 502,
          isOpenMultiLine: isOpenMultiLine || 0,
        };

        delete iObj.addressList;

        if (addressList && addressList.length) {
          const newAddressList = [];

          if (connectType === 's7' || connectType === 'opcua') {
            for (const item of addressList) {
              const { name, funId, offsetId, nodeId, type } = item;

              if (funId) {
                const data = { parameterName: name, parameterCode: funId };

                const obj = gatherParameterList.value.find((item) => item.parameterCode === funId);

                if (obj) {
                  data['parameterId'] = obj.value;

                  data['isCreate'] = false;
                } else {
                  data['parameterId'] = uuidv4();

                  data['isCreate'] = true;
                }

                if (connectType === 's7') {
                  data['s7Address'] = offsetId;
                } else if (connectType === 'opcua') {
                  data['opcuaAddress'] = nodeId;

                  data['opcuaType'] = type;
                }

                newAddressList.push(data);
              }
            }
          } else if (connectType === 'modbus' || connectType === 'fins') {
            for (const item of addressList) {
              const { list, id, slaveId } = item;

              if (list && list.length) {
                for (const lItem of list) {
                  const {
                    name,
                    funId,
                    type,
                    leng,
                    decimalPlaces,
                    address,
                    finsAddress = null,
                    byteOrder = 'none',
                    computedType = 'none',
                    computedNum = 0,
                    bitFunIdObj = null,
                  } = lItem;

                  // console.log(lItem)

                  if (funId) {
                    let newSlaveId = slaveId || id || null;

                    if (newSlaveId === '0A') {
                      newSlaveId = parseInt(newSlaveId, 16).toString();
                    }

                    const data = {
                      slaveId: newSlaveId,
                      parameterName: name,
                      parameterCode: funId,
                      type,
                      leng,
                      decimalPlaces,
                      startOffset: 0,
                      address,
                      finsAddress,
                      byteOrder,
                      computedType,
                      computedNum,
                      bitAccessCodeObj: bitFunIdObj ? JSON.stringify(bitFunIdObj) : null,
                    };

                    const obj = gatherParameterList.value.find(
                      (item) => item.parameterCode === funId
                    );

                    if (obj) {
                      data['parameterId'] = obj.value;

                      data['isCreate'] = false;
                    } else {
                      data['parameterId'] = uuidv4();

                      data['isCreate'] = true;
                    }

                    newAddressList.push(data);
                  }
                }
              }
            }
          }

          iObj['addressList'] = newAddressList;
        }

        console.log(iObj);

        return iObj;
      },
      submitDataFn: addMachineParameter,
    },
  };

  const initDictData = async () => {
    const res = await Promise.all([listMachine(), listGatherParameter()]);

    const [list1, list2] = res;

    machineList.value =
      list1?.data.map((item) => ({ label: item.machineName, value: item.machineCode })) || [];

    gatherParameterList.value =
      list2?.data.map((item) => ({
        label: item.parameterName,
        value: item.id,
        parameterCode: item.parameterCode,
        parameterName: item.parameterName,
        isCreate: false,
      })) || [];
  };

  initDictData();
</script>
